热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

框图|正反_AndroidCamera打开预览流程分析打开camera的SDK流程

篇首语:本文由编程笔记#小编为大家整理,主要介绍了AndroidCamera打开预览流程分析--打开camera的SDK流程相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Android Camera 打开预览流程分析--打开camera的SDK流程相关的知识,希望对你有一定的参考价值。


android系统应用场景中,Camera的使用场景变得越来越重要,在手机端不管是牌照美颜,还是拍小视频上传小视频平台。在其他领域,如车载,倒车视频,360全景影像也同样会用到Camera接口。那我们这个系列就拿Camera来分析了,我们主要就是android camera流程进行一个分析,对于照片美颜,视频上传这些就不在我们关注的范围了。那我们分析还是带着问题去分析吧,Camera就如何打开的,现在一个手机上少则2,3个摄像头,多着5~6个摄像头,那如何去打开想要的那个摄像头呢。另一方面的问题就是Camera预览窗口的图像是如何传到我们打开的那个窗口的,经过了那些流程呢。我们后续的分析文章就围绕着两个方面来展开分析。
## Camera的分层框架 (等分析完这两个流程,应该就可以画出这个框图了)
HAL层服务:frameworks/hardware/interfaces/cameraservice
FW层服务: frameworks/av/services/camera/libcameraservice
FW层SDK: frameworks/base/core/java/android/hardware/camera(2)

Camera的打开

我们就从android 标准的camera open接口开始撸:

open() ------framework/base/core/java/android/hardware/camera.java
new Camera(int id)
cameraInitVersion(int cameraId, int halVersion)
native_setup(new WeakReference<Camera>(this), cameraId, halVersion, packageName)
android_hardware_Camera_native_setup(..., jint cameraId, jint halVersion, jstring clientPackageName) -----framework/base/core/jni/android_hardware_camera.cpp

Camera从open接口开始分析&#xff0c;直接就调用到JNI中去了&#xff0c;我们接着从JNI中继续分析&#xff1a;

static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
jobject weak_this, jint cameraId, jint halVersion, jstring clientPackageName)

...
//调用camera的connect接口 打开camera
camera &#61; Camera::connect(cameraId, clientName,
Camera::USE_CALLING_UID, Camera::USE_CALLING_PID);
...
sp<JNICameraContext> context &#61; new JNICameraContext(env, weak_this, clazz, camera);
context->incStrong((void*)android_hardware_Camera_native_setup);
camera->setListener(context);
// save context in opaque field
env->SetLongField(thiz, fields.context, (jlong)context.get());
// Update default display orientation in case the sensor is reverse-landscape
CameraInfo cameraInfo;
//获取camera的信息
status_t rc &#61; Camera::getCameraInfo(cameraId, &cameraInfo);
...

从JNI的native_setup中可以看到&#xff0c;调用了camera的connect接口&#xff0c;成功打开之后就可以获取camera的信息了. 再往下分析时&#xff0c;发现很多不对劲的地方&#xff0c;网上去百度了下&#xff0c;发现我们现在分析的camera 接口是Camera 最早的接口了&#xff0c;现在基本被弃用了&#xff0c;现在基本都是是使用Camera2的API接口&#xff0c;Camera2 与Camera 接口还是有挺大区别。Camera接口都被弃用了&#xff0c;我们就直接上手分析Camera2的接口吧。


Camera2 的接口

上面有说到camera 已经被弃用了&#xff0c;都推荐使用camera2的接口。我们就直接再从camera2 开始分析。camer2中有好些类&#xff1a;
CameraManager
相机系统服务&#xff0c;用于管理和连接相机设备
CameraDevice
相机设备类&#xff0c;和Camear1中的Camera类似
CameraCharacteristics
用于获取相机信息&#xff0c;内部携带大量的相机信息&#xff0c;包括摄像头的正反等&#xff0c;和Camear1中的Camera.Parameters同等功能。
CameraRequest
相机捕获图像的设置请求&#xff0c;包括sensor, flashlight等
CameraCaptureSession
请求抓去相机图像帧的会话&#xff0c;会话会创建一个通道&#xff0c;一个CameraDevice只能打开一个CameraCaptureSession.源头是Target, Target可以是Preview, 也可以是ImageReader


打开相机

public void Open()
CameraManager cameraManager &#61; (CameraManager)getSystemService(Context.CAMERA_SERVICE);
for(String cameraId: cameraManager.getCameraIdList())
CameraCharacteristics characteristics &#61; cameraManager.getCameraCharacteristics(cameraId);
//打开相机&#xff0c;第一个参数&#xff1a;哪个摄像头&#xff0c;第二个参数mStateCallback为相机打开的回调接口&#xff0c;第三个参数用来确定callback在哪个线程中执行&#xff0c;为null的话&#xff0c;在当前线程中执行
cameraManager.openCamera(cameraId, mStateCallback, null)


private final CameraDevice.StateCallback mStateCallback &#61; new CameraDevice.StateCallback()
public void onOpened(CameraDevice camera)
mCameraDevice &#61; camera;
...


public void onDisconnected(CameraDevice camera)
camera.close();
mCameraDevice &#61; null;

public void onError()CameraDevice camera, int error
camera.close();
mCameraDevice &#61; null;


打开Camera时将CameraDevice.StateCallback对象传给openCamera当做参数&#xff0c;在OnOpened的回调中&#xff0c;再把Camera对象传给mCameraDevice, 后面就是用mCameraDevice 来操作。
那我们看看CameraManager.openCamera的流程吧。

public void openCamera(&#64;NonNull String cameraId,
&#64;NonNull final CameraDevice.StateCallback callback, &#64;Nullable Handler handler)
throws CameraAccessException
openCameraForUid(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),
USE_CALLING_UID);

public void openCameraForUid(&#64;NonNull String cameraId,
&#64;NonNull final CameraDevice.StateCallback callback, &#64;NonNull Executor executor,
int clientUid)
throws CameraAccessException
......
openCameraDeviceUserAsync(cameraId, callback, executor, clientUid);

private CameraDevice openCameraDeviceUserAsync(String cameraId,
CameraDevice.StateCallback callback, Executor executor, final int uid)
throws CameraAccessException
CameraCharacteristics characteristics &#61; getCameraCharacteristics(cameraId);
CameraDevice device &#61; null;
synchronized (mLock)
ICameraDeviceUser cameraUser &#61; null;
//初始化android.hardware.camera2.impl.CameraDeviceImpl
android.hardware.camera2.impl.CameraDeviceImpl deviceImpl &#61;
new android.hardware.camera2.impl.CameraDeviceImpl(
cameraId,
callback,
executor,
characteristics,
mContext.getApplicationInfo().targetSdkVersion);
ICameraDeviceCallbacks callbacks &#61; deviceImpl.getCallbacks();

//初始化CameraService
ICameraService cameraService &#61; CameraManagerGlobal.get().getCameraService();
//CameraService 连接设备
cameraUser &#61; cameraService.connectDevice(callbacks, cameraId,
mContext.getOpPackageName(), uid);
deviceImpl.setRemoteDevice(cameraUser);
device &#61; deviceImpl;

return device;

这一步调用就直接调用到CameraService 里去了&#xff0c;与其他服务不同的是&#xff0c;其他服务直接是在SystemServer里的一个服务&#xff0c;CameraService是运行在CameraServer的一个独立进程中的。里面是使用cpp代码写的一个进程。下篇我们继续研究这个CameraService进程。


推荐阅读
author-avatar
乌龟北京飘
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有